package com.madzone.wiki.gae.ds;

import java.security.Principal;
import java.sql.PreparedStatement;
import java.util.List;
import java.util.Properties;

import com.ecyrd.jspwiki.NoRequiredPropertyException;
import com.ecyrd.jspwiki.WikiEngine;
import com.ecyrd.jspwiki.auth.NoSuchPrincipalException;
import com.ecyrd.jspwiki.auth.WikiSecurityException;
import com.ecyrd.jspwiki.auth.user.AbstractUserDatabase;
import com.ecyrd.jspwiki.auth.user.DefaultUserProfile;
import com.ecyrd.jspwiki.auth.user.DuplicateUserException;
import com.ecyrd.jspwiki.auth.user.UserProfile;
import com.madzone.wiki.gae.ds.model.User;

public class GoogleDataStoreUserDatabase extends AbstractUserDatabase {
	
	private WikiEngine mWikiEngine;
	private Properties mProperties;
	private static final String NOTHING = "";

	@Override
	public UserProfile findByEmail(String emailId)
			throws NoSuchPrincipalException {
		User user = User.getByEmailId(emailId);
		if (user == null) {
			throw new NoSuchPrincipalException(emailId);
		}
		return getUserProfile(user);
	}
	
	public UserProfile getUserProfile(User user) {
		UserProfile userProfile = DefaultUserProfile.newProfile(this);
		userProfile.setCreated(user.getCreated());
		userProfile.setEmail(user.getEmail());
		userProfile.setFullname(user.getFullName());
		userProfile.setLastModified(user.getModified());
		userProfile.setLockExpiry(user.getLockExpiry());
		userProfile.setLoginName(user.getLoginName());
		userProfile.setPassword(user.getPassword());
		return userProfile;
	}

	@Override
	public UserProfile findByFullName(String fullName)
			throws NoSuchPrincipalException {
		User user = User.getByFullName(fullName);
		if (user == null) {
			throw new NoSuchPrincipalException(fullName);
		}
		return getUserProfile(user);
	}

	@Override
	public UserProfile findByLoginName(String loginName)
			throws NoSuchPrincipalException {
		User user = User.getByLoginName(loginName);
		if (user == null) {
			throw new NoSuchPrincipalException(loginName);
		}
		return getUserProfile(user);
	}

	@Override
	public UserProfile findByWikiName(String wikiName)
			throws NoSuchPrincipalException {
		User user = User.getByWikiName(wikiName);
		if (user == null) {
			throw new NoSuchPrincipalException(wikiName);
		}
		return getUserProfile(user);
	}

	@Override
	public void initialize(WikiEngine engine, Properties props)
			throws NoRequiredPropertyException {
		mWikiEngine = engine;
		mProperties = props;
	}

	@Override
	public void save(UserProfile profile) throws WikiSecurityException {
		// Figure out which prepared statement to use & execute it
        String loginName = profile.getLoginName();
        UserProfile existingProfile = null;
        try
        {
            existingProfile = findByLoginName( loginName );
        }
        catch( NoSuchPrincipalException e )
        {
            // Existing profile will be null
        }

        // Get a clean password from the passed profile.
        // Blank password is the same as null, which means we re-use the
        // existing one.
        String password = profile.getPassword();
        String existingPassword = (existingProfile == null) ? null : existingProfile.getPassword();
        if( NOTHING.equals( password ) )
        {
            password = null;
        }
        if( password == null )
        {
            password = existingPassword;
        }

        // If password changed, hash it before we save
        if( !password.equals( existingPassword ) )
        {
            password = getHash( password );
        }
		User user = User.getByLoginName(profile.getLoginName());
		if (user == null) {
			user = new User();
		}
		user.setCreated(profile.getCreated());
		user.setEmail(profile.getEmail());
		user.setFullName(profile.getFullname());
		user.setLockExpiry(profile.getLockExpiry());
		user.setLoginName(profile.getLoginName());
		user.setModified(profile.getLastModified());
		user.setPassword(password);
		user.setWikiName(profile.getWikiName());
		user.setUid(profile.getUid());
		user.save();
	}

	@Override
	public void deleteByLoginName(String loginName)
			throws NoSuchPrincipalException, WikiSecurityException {
		User user = User.getByLoginName(loginName);
		if (user == null) {
			throw new NoSuchPrincipalException(loginName);
		}
		user.delete();
	}

	@Override
	public UserProfile findByUid(String uid) throws NoSuchPrincipalException {
		User user = User.getByUid(uid);
		if (user == null) {
			throw new NoSuchPrincipalException(uid);
		}
		return getUserProfile(user);
	}

	@Override
	public Principal[] getWikiNames() throws WikiSecurityException {
		List<User> users = User.getAllUsers();
		Principal[] principals = new Principal[users.size()];
		int i = 0;
		for(final User user:users) {
			principals[i] = new Principal() {
				private String name = user.getLoginName();
				@Override
				public String getName() {
					return name;
				}
				
			};
			i++;
		}
		return principals;
	}

	@Override
	public void rename(String loginName, String newName)
			throws NoSuchPrincipalException, DuplicateUserException,
			WikiSecurityException {
		User user = User.getByLoginName(loginName);
		if (user == null) {
			throw new NoSuchPrincipalException(loginName);
		}
		user.setLoginName(newName);
		user.save();
	}

}
